﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;

namespace SIR
{
	namespace Area
	{
		public class Database
		{
			public const ushort Total = 20;
			public const string Connect = "Connect (Total: 5)";
			public const string Read = "Read (Total: 4)";
			public const string Insert = "Insert (Total: 3)";
			public const string Update = "Update (Total: 4)";
			public const string Delete = "Delete (Total: 4)";
		}

		public class DataAccessLayer
		{
			public const ushort Total = 20;
			public const string Connect = "Connect (Total: 5)";
			public const string Read = "Read (Total: 4)";
			public const string Insert = "Insert (Total: 3)";
			public const string Update = "Update (Total: 4)";
			public const string Delete = "Delete (Total: 4)";
		}

		public class ImageProcessing
		{
			public const ushort Total = 2;
			public const string ProcessQueue = "Process Queue (Total: 1)";
			public const string AnalyzeImage = "Analyze Image (Total: 1)";
		}

		public class Search
		{
			public const ushort Total = 15;
			public const string NoResults = "No Results (Total: 3)";
			public const string Error = "Error (Total: 3)";
			public const string ByImage = "By Image (Total: 3)";
			public const string ByColorBalance = "By Color Balance (Total: 3)";
			public const string ByPattern = "By Pattern (Total: 3)";
		}

		public class UserProfile
		{
			public const ushort Total = 48;
			public const string Register = "Register (Total: 5)";
			public const string LogIn = "Log In (Total: 5)";
			public const string LogOut = "Log Out (Total: 1)";
			public const string ChangePassword = "ChangePassword (Total: 3)";
			public const string PasswordReset = "PasswordReset (Total: 2)";
			public const string ViewLibrary = "View Library (Total: 2)";
			public const string UploadPicture = "Upload Picture (Total: 2)";
			public const string CreateFolder = "Create Folder (Total: 3)";
			public const string MovePictureFolder = "Move Picture/Folder (Total: 5)";
			public const string RenamePictureFolder = "Rename Picture/Folder (Total: 5)";
			public const string DeletePictureFolder = "Delete Picture/Folder (Total: 3)";
			public const string AddFavorite = "Add Favorite (Total: 3)";
			public const string ViewFavorites = "View Favorties (Total: 2)";
			public const string RemoveFavorite = "Remove Favorite (Total: 3)";
			public const string ChangePrivacySetting = "Change Privacy Setting (Total: 4)";
		}

		public class WebInterfaces
		{
			public const ushort Total = 15 + 49;
			public const string NoResults = "Search - No Results (Total: 3)";
			public const string Error = "Search - Error (Total: 3)";
			public const string ByImage = "Search - By Image (Total: 3)";
			public const string ByColorBalance = "Search - By Color Balance (Total: 3)";
			public const string ByPattern = "Search - By Pattern (Total: 3)";
			public const string Register = "User Profile - Register (Total: 5)";
			public const string LogIn = "User Profile - Log In (Total: 5)";
			public const string LogOut = "User Profile - Log Out (Total: 1)";
			public const string ChangePassword = "User Profile - ChangePassword (Total: 3)";
			public const string PasswordReset = "User Profile - PasswordReset (Total: 2)";
			public const string ViewLibrary = "User Profile - View Library (Total: 2)";
			public const string UploadPicture = "User Profile - Upload Picture (Total: 3)";
			public const string CreateFolder = "User Profile - Create Folder (Total: 3)";
			public const string MovePictureFolder = "User Profile - Move Picture/Folder (Total: 5)";
			public const string RenamePictureFolder = "User Profile - Rename Picture/Folder (Total: 5)";
			public const string DeletePictureFolder = "User Profile - Delete Picture/Folder (Total: 3)";
			public const string AddFavorite = "User Profile - Add Favorite (Total: 3)";
			public const string ViewFavorites = "User Profile - View Favorties (Total: 2)";
			public const string RemoveFavorite = "User Profile - Remove Favorite (Total: 3)";
			public const string ChangePrivacySetting = "User Profile - Change Privacy Setting (Total: 4)";
		}
	}

	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
	public sealed class SIRTestCategory : TestCategoryBaseAttribute
	{
		/// <summary>
		/// Builds a complext category structure and traits to provide complex structuring in the VS Test explorer
		/// </summary>
		/// <param name="area">The Area of the application</param>
		/// <param name="useCase">The name of the use case</param>
		/// <param name="testCaseNumber">The number this test is within the set for the use case</param>
		/// <param name="classType">The type of class that contains the test</param>
		public SIRTestCategory(Type area, string useCase, ushort testCaseNumber, Type classType)
		{
			// Get the total number of test cases for the area
			ushort total = 0;
			if (area == typeof(Area.Database))
			{
				total = Area.Database.Total;
			}
			else if (area == typeof(Area.DataAccessLayer))
			{
				total = Area.DataAccessLayer.Total;
			}
			else if (area == typeof(Area.ImageProcessing))
			{
				total = Area.ImageProcessing.Total;
			}
			else if (area == typeof(Area.Search))
			{
				total = Area.Search.Total;
			}
			else if (area == typeof(Area.UserProfile))
			{
				total = Area.UserProfile.Total;
			}
			else if (area == typeof(Area.WebInterfaces))
			{
				total = Area.WebInterfaces.Total;
			}

			// Add the categories
			AddCategories(
				string.Format("Area: {0} (Total: {1})", area.Name, total.ToString()),
				string.Format("Use Case: {0} - {1}", area.Name, useCase),
				string.Format("Test Case #: {0}", testCaseNumber.ToString()),
				string.Format("Class: {0}", classType.FullName)
				);
		}

		/// <summary>
		/// Adds the categories to the list
		/// </summary>
		/// <param name="categories">Categores to be added</param>
		private void AddCategories(params string[] categories)
		{
			foreach (var category in categories)
				_categories.Add(category);
		}

		private readonly IList<string> _categories = new List<string>();
		/// <summary>
		/// Get the categories for the method
		/// </summary>
		public override IList<string> TestCategories { get { return _categories; } }
	}
}
